﻿using System;
using System.ComponentModel;
using System.Web.UI.WebControls;
using System.Web;
using System.Web.UI;

namespace MyLib.Web.UI {
	/// <summary>
	/// 
	/// </summary>
	[ToolboxData("<{0}:MyRangeValidator runat=\"server\"></{0}:MyRangeValidator>")]
	public class MyRangeValidator : System.Web.UI.WebControls.RangeValidator {
		private bool m_initialized = false;

		/// <summary>
		/// 
		/// </summary>
		protected virtual void UpdateErrorMessage() {
			if (m_initialized) {
				var flag1 = string.IsNullOrWhiteSpace(MinimumValue);
				var flag2 = string.IsNullOrWhiteSpace(MaximumValue);
				if (flag1 && !flag2) {
					ErrorMessage = string.Format(Properties.Main.ErrorTooLarge, PropertyTitle, MaximumValue);
				} else if (!flag1 && flag2) {
					ErrorMessage = string.Format(Properties.Main.ErrorTooSmall, PropertyTitle, MinimumValue);
				} else if (!flag1 && !flag2) {
					ErrorMessage = string.Format(Properties.Main.ErrorOutOfRange, PropertyTitle, MinimumValue, MaximumValue);
				}
			}
		}

		/// <summary>
		/// 
		/// </summary>
		[Category("Appearance")]
		[Bindable(true)]
		[Browsable(true)]
		[DefaultValue("")]
		public string PropertyTitle {
			get {
				var obj = ViewState["PropertyTitle"];

				return obj == null ? "" : (string)obj;
			}
			set {
				ViewState["PropertyTitle"] = value;

				UpdateErrorMessage();
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="e"></param>
		protected override void OnInit(EventArgs e) {
			base.OnInit(e);

			Display = System.Web.UI.WebControls.ValidatorDisplay.Dynamic;
			SetFocusOnError = true;

			m_initialized = true;
			if (string.IsNullOrWhiteSpace(ErrorMessage)) {
				UpdateErrorMessage();
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="e"></param>
		protected override void OnLoad(EventArgs e) {
			var ctrl = NamingContainer.FindControl(ControlToValidate);

			if (ctrl != null && ctrl is MyTextBox) {
				var tb = (MyTextBox)ctrl;

				switch (tb.TextFormat) {
					case TextFormat.Currency:
						Type = ValidationDataType.Currency;
						break;
					case TextFormat.Double:
					case TextFormat.Percent:
						Type = ValidationDataType.Double;
						break;
					case TextFormat.Integer:
						Type = ValidationDataType.Integer;
						break;
					case TextFormat.Date:
					case TextFormat.DateTime:
					case TextFormat.Time:
						Type = ValidationDataType.Date;
						break;
					default:
						Type = ValidationDataType.String;
						break;
				}
			}

			base.OnLoad(e);
		} // end of OnLoad.

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		protected override bool ControlPropertiesValid() {
			ValidateValues();
			return true;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		protected override bool EvaluateIsValid() {
			string text = base.GetControlValidationValue(base.ControlToValidate);
			if (text.Trim().Length == 0) {
				return true;
			}
			if (base.Type == ValidationDataType.Date && !this.DetermineRenderUplevel()) {
				DateTime dateTime;
				if (DateTime.TryParse(text,
					System.Globalization.CultureInfo.CurrentCulture,
					System.Globalization.DateTimeStyles.None,
					out dateTime)) {

					text = dateTime.ToShortDateString();
				}
			}

			var flag1 = string.IsNullOrWhiteSpace(MinimumValue);
			var flag2 = string.IsNullOrWhiteSpace(MaximumValue);
			if (flag1 && !flag2) {
				return BaseCompareValidator.Compare(text, false, this.MaximumValue, base.CultureInvariantValues, ValidationCompareOperator.LessThanEqual, base.Type);
			} else if (!flag1 && flag2) {
				return BaseCompareValidator.Compare(text, false, this.MinimumValue, base.CultureInvariantValues, ValidationCompareOperator.GreaterThanEqual, base.Type);
			} else if (!flag1 && !flag2) {
				return BaseCompareValidator.Compare(text, false, this.MinimumValue, base.CultureInvariantValues, ValidationCompareOperator.GreaterThanEqual, base.Type) && BaseCompareValidator.Compare(text, false, this.MaximumValue, base.CultureInvariantValues, ValidationCompareOperator.LessThanEqual, base.Type);
			} else {
				return true;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		private void ValidateValues() {
			var flag1 = string.IsNullOrWhiteSpace(MinimumValue);
			var flag2 = string.IsNullOrWhiteSpace(MaximumValue);

			string maximumValue = this.MaximumValue;
			if (!flag2 && !BaseCompareValidator.CanConvert(maximumValue, base.Type, base.CultureInvariantValues)) {
				throw new HttpException(string.Format(
					@"Value of ""{2}.{1}"" is ""{0}"", can not be convert to {3}. ",
					maximumValue,
					"MaximumValue",
					this.ID,
					PropertyConverter.EnumToString(typeof(ValidationDataType), base.Type)
				));
			}
			string minimumValue = this.MinimumValue;
			if (!flag1 && !BaseCompareValidator.CanConvert(minimumValue, base.Type, base.CultureInvariantValues)) {
				throw new HttpException(string.Format(
					@"Value of ""{2}.{1}"" is ""{0}"", can not be convert to {3}. ",
					minimumValue,
					"MinimumValue",
					this.ID,
					PropertyConverter.EnumToString(typeof(ValidationDataType), base.Type)
				));
			}
			if (!flag1 && !flag2 && BaseCompareValidator.Compare(minimumValue, base.CultureInvariantValues, maximumValue, base.CultureInvariantValues, ValidationCompareOperator.GreaterThan, base.Type)) {
				throw new HttpException(string.Format(
					@"Range of ""{2}"" is ""{0}"" and ""{1}"", overlaped. ",
					minimumValue,
					maximumValue,
					this.ID
				));
			}
		} // end of ValidateValues.
	} // end of MyFormatBaseValidator.
}
